﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Windows.Forms;
using DevExpress.XtraEditors;
using ProgramMain.Database;
using ProgramMain.Framework;
using ProgramMain.Google;

namespace ProgramMain.OpticNet
{
    public partial class FrmHotCableTunnels : ProgramMain.Framework.frmBase
    {
        private int? _activeVertexID = null;
        protected int? ActiveVertexID
        {
            get { return _activeVertexID; }
            set
            {
                if (_activeVertexID !=value)
                {
                    _activeVertexID = value;
                    cableTunnelList1.SetFilter(сheckFilterTunel.Checked ? _activeVertexID : null);
                }
            }
        }

        public bool AutoCloseVertexDetail
        {
            set
            {
                vertexList1.AutoCloseDetail = value;
                cableTunnelList1.AutoCloseDetail = value;
            }
        }

        public FrmHotCableTunnels()
        {
            InitializeComponent();
          //cableTunnelList1.AutoAcceptChanges = true;
        }

        public void EditCoordinateNewVertex(int ObjectID, Coordinate coordinate)
        {
            SimpleOpticNetDB.VertexesRow vertex = vertexList1.FindVertex(ObjectID);
            Coordinate oldCoordinate = new Coordinate(vertex.Longitude,vertex.Latitude);
            vertexList1.EditCoordinateNewVertex(ObjectID, coordinate);
            cableTunnelList1.EditCoordinateNewCableTunnels(coordinate, oldCoordinate);
        }

        public event EventHandler<CableTunnelList.AcceptChangesArgs> OnAcceptChanges;
        public event EventHandler<GlobalData.ListEventArgs> OnCancelCableTunnel;

        public event EventHandler<VertexList.AcceptChangesArgs> OnVertexChanges;
        public event EventHandler<GlobalData.ListEventArgs> OnCancelVertexes;

        public bool AddVertex(SimpleOpticNetDB.VertexesRow row)
        {
            bool newVertex = vertexList1.AutoAddCableTunnel(row);
            if (newVertex)
            {
                cableTunnelList1.AutoAddCableTunnel(row);
                сheckFilterTunel.Checked = false;
            }
            return newVertex;
        }

        public void EditNewVertex(int vertexID)
        {
            vertexList1.EditNewVertex(vertexID);
        }

        public void EditNewCableTunnel(int CableTunnelID)
        {
            cableTunnelList1.EditNewCableTunnel(CableTunnelID);
        }

        public void AddVertex(Coordinate coordinate)
        {
            сheckFilterTunel.Checked = false;
            SimpleOpticNetDB.VertexesRow row = vertexList1.AddVertex(coordinate);
            if (row != null) AddVertex(row);
        }

        public void DeleteVertex(int vertexID)
        {
            vertexList1.DeleteVertex(vertexID);
        }

        private void cableTunnelList1_OnAcceptChanges(object sender, CableTunnelList.AcceptChangesArgs e)
        {
            if (OnAcceptChanges != null)
                OnAcceptChanges(this, e);
        }

        private void FrmHotCableTunnels_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (cableTunnelList1.DataSourceChanged)
            {
                DialogResult result = XtraMessageBox.Show("Вы не сохранили созданный туннель в базе данных! Для сохранения туннеля используйте кнопку 'Сохранить туннель'. Сохранить туннель при выходе?", "Предупреждение", MessageBoxButtons.YesNoCancel);
                e.Cancel = result == DialogResult.Cancel;
                if (result == DialogResult.Yes)
                {
                    btnSave_ItemClick(null, null);
                }
                if(result == DialogResult.No)
                {
                    ClearNewWork(vertexList1.GetVertexesID(true), cableTunnelList1.GetCableTunnelsID(true));
                }
            }
        }

        private void ClearNewWork(List<int> vertexesID, List<int> cableTunnelID)
        {
            if (cableTunnelID != null && OnCancelCableTunnel != null)
                OnCancelCableTunnel(this, new GlobalData.ListEventArgs(cableTunnelID));

            if (vertexesID != null && OnCancelVertexes != null)
                OnCancelVertexes(this, new GlobalData.ListEventArgs(vertexesID));
        }

        private void CreateNewWork()
        {
            if (cableTunnelList1.SimpleOpticNetDB != null && OnAcceptChanges != null)
                OnAcceptChanges(this, new CableTunnelList.AcceptChangesArgs(cableTunnelList1.SimpleOpticNetDB.CableTunnels));

            if (vertexList1.SimpleOpticNetDB != null && OnVertexChanges != null)
                OnVertexChanges(this, new VertexList.AcceptChangesArgs(vertexList1.SimpleOpticNetDB.Vertexes));
        }

        public int CableID { get; private set; }

        private int CreateCable(int? vertex1ID, int? vertex2ID)
        {
            SimpleOpticNetDB.CableRow cableRow = new CableList().AddCable();
            if (cableRow == null || cableRow.ID == 0)
            return 0;
            if (cableRow != null && cableRow.ID > 0)
            {
              if (vertex1ID.HasValue)
                {
                    SimpleOpticNetDB.CableVertexRow row1 =
                        (SimpleOpticNetDB.CableVertexRow) ((DataRowView) CableVertex.AddNew()).Row;
                    row1.VertexID = vertex1ID.Value;
                    row1.CableID = cableRow.ID;
                    row1.EndEdit();
                }
                if (vertex2ID.HasValue)
                {
                    SimpleOpticNetDB.CableVertexRow row2 =
                        (SimpleOpticNetDB.CableVertexRow) ((DataRowView) CableVertex.AddNew()).Row;
                    row2.VertexID = vertex2ID.Value;
                    row2.CableID = cableRow.ID;
                    row2.EndEdit();
                }
                CableVertex.EndEdit();
                cableVertexTableAdapter.SetUpdateTimeout = ProgramMain.Properties.Settings.Default.LongQueryTimeout;
                cableVertexTableAdapter.Update(simpleOpticNetDB.CableVertex);

                foreach (int item in cableTunnelList1.GetCableTunnelsID())
                {
                    SimpleOpticNetDB.CableLinkRow cableLinkRow =
                        (SimpleOpticNetDB.CableLinkRow) ((DataRowView) CableLink.AddNew()).Row;
                    cableLinkRow.CableID = cableRow.ID;
                    cableLinkRow.CableTunnelID = item;
                }
                CableLink.EndEdit();
                cableLinkTableAdapter.SetUpdateTimeout = ProgramMain.Properties.Settings.Default.LongQueryTimeout;
                cableLinkTableAdapter.Update(simpleOpticNetDB.CableLink);
            }
            return cableRow.ID;
        }

        private void btnSave_ItemClick(object sender, EventArgs e)
        {
            if (cableTunnelList1.CableTunnelCount > 0)
            {
                
                ClearNewWork(vertexList1.GetVertexesID(true), cableTunnelList1.GetCableTunnelsID(true));
                vertexList1.UpdateDataRow();
                cableTunnelList1.DBWrite();
                CreateNewWork();

                if (XtraMessageBox.Show("Проложить кабель в туннель?", "Сообщение", MessageBoxButtons.YesNo,
                                        MessageBoxIcon.Exclamation) == DialogResult.Yes)
                {
                    int? vertex1ID = null;
                    int? vertex2ID = null;
                    vertexList1.GetVertexesTerminated(out vertex1ID, out vertex2ID);
                    if (vertex1ID.HasValue && vertex2ID.HasValue)
                    {
                        CableID = CreateCable(vertex1ID, vertex2ID);
                        this.Close();
                    }
                }
            }
            else
            {
                XtraMessageBox.Show("Не задано ни одного туннкля для прокладки", "Сообщение", MessageBoxButtons.OK);
            }
            //   cableTunnelList1.GridListChanged = false;
        }

        private void FrmHotCableTunnels_Load(object sender, EventArgs e)
        {
            vertexList1.SimpleOpticNetDB = this.simpleOpticNetDB;
            cableTunnelList1.SimpleOpticNetDB = this.simpleOpticNetDB;

            tableAdapterManager.CableTunnelsTableAdapter = cableTunnelList1.cableTunnelsTableAdapter;
            tableAdapterManager.VertexesTableAdapter = vertexList1.vertexesTableAdapter;

            vertexList1.EUpdateDataRow += cableTunnelList1.AfterNewVertex;
            vertexList1.EDeleteDataRow += cableTunnelList1.DeleteVertex;
            cableTunnelList1.FindVertex += vertexList1.FindVertex;
        }

        private void vertexList1_ViewRowIDChanged(object sender, BaseDetailCtl.ShowDetailEventArgs e)
        {
            ActiveVertexID = e.DetailID;
        }

        private void сheckFilterTunel_CheckedChanged(object sender, DevExpress.XtraBars.ItemClickEventArgs e)
        {
            cableTunnelList1.SetFilter(сheckFilterTunel.Checked ? _activeVertexID : null);
        }

        private void vertexList1_OnAcceptChanges(object sender, VertexList.AcceptChangesArgs e)
        {
            if(OnVertexChanges != null) OnVertexChanges(this, new VertexList.AcceptChangesArgs(e.DataTable));
        }
      
       private void vertexList1_EAfterDataRow(object sender, EventUpdateRow e)
       {
          ClearNewWork(_vertexesId, _cableTunnelId);
          CreateNewWork();
       }

       private void btnAddVertex_MouseDown(object sender, MouseEventArgs e)
       {
           MapDragObject.StartNewVertexDragDrop(this);
       }

        private List<int> _vertexesId;
        private List<int> _cableTunnelId;
        private void vertexList1_EBeforeDataRow(object sender, GlobalData.ListEventArgs e)
       {
           _vertexesId = e.IDList;
           _cableTunnelId = cableTunnelList1.GetCableTunnelsID(true);
       }

        private void cableTunnelList1_EAfterDataRow(object sender, EventUpdateRow e)
        {
            ClearNewWork(null, _cableTunnelId); 
            CreateNewWork();
        }

        private void cableTunnelList1_EBeforeDataRow(object sender, GlobalData.ListEventArgs e)
        {
            _cableTunnelId = e.IDList;
        }

        public void DeleteCableTunnel(int CableTunnelID)
        {
            cableTunnelList1.DeleteCableTunnel(CableTunnelID);
        }
    }
    
    public class EventUpdateRow : EventArgs
    {
        private Nullable<Int32> _dataSoutceId;
        private Nullable<Int32> _dataBase_Id;
        public EventUpdateRow(Nullable<Int32> dataSoutceId, Nullable<Int32> dataBase_Id)
        {
            _dataSoutceId = dataSoutceId;
            _dataBase_Id = dataBase_Id;
        }

        public Nullable<Int32> DataSoutceId
        { get { return _dataSoutceId; } }

        public Nullable<Int32> DataBaseId
        { get { return _dataBase_Id; } }
    }

}